(function($, undefined) {
	$.widget("itex.dropdown", {
		options : {
			direction : "down"
		},

		_select : function(i) {
			var label = $("span.value", this.options.container);
			this.element.hide();
			label.html($(i).html());
			if (this.options.selector) {
				var data = $(i).data(this.options.selector);
				if (data)
					label.data(this.options.selector, data);
				else
					label.removeData(this.options.selector);
			}
			if (this.options.callback)
				this.options.callback($(i));
		},

		value : function(val) {
			if (val) {
				var li = $("li[data-" + this.options.selector + "=" + val + "]", this.element);
				if (li)
					this._select($("li[data-" + this.options.selector + "=" + val + "]", this.element));
				else
					$("span.value", this.options.container).removeData(this.options.selector);
			} else {
				var val =$("span.value", this.options.container).data(this.options.selector); 
				return val ? val : null;
			}
		},

		_create : function() {
			var up = true;
			var self = this;
			this.element.addClass("dropdown-menu");
			if (this.options.direction == "down")
				up = false;

			var widget = $("<div class='select-dropdown'></div>");
			this.options["container"] = widget;
			var toggle = $("<a class='dropdown-toggle' data-toggle='dropdown' href='#'></a>");
			toggle.append("<span class='value'></span>");
			var list = $(this.element);
			if (up)
				widget.append(list.replaceWith(widget)).append(toggle);
			else
				widget.append(toggle).append(list.replaceWith(widget));
			var label = widget.find('span.value');
			var shown = false;
			toggle.click(function(event) {
				$(".dropdown-menu").each(function() {
					if (this != list[0])
						$(this).css("display", "none");
				});
				list.toggle();
				if (!shown) {
					if (up)
						list.css("top", -list.height() - 14);
					var container = list.closest("div.ui-dialog-content");
					if (container.length == 0)
						container = list.closest("body");

					if (list.offset().left + list.width() > container.width())
						list.css("left", -(list.offset().left + list.width() - container.width() + 15) + "px");

					shown = true;
					list.toggle();
					list.toggle();
				}
				event.stopPropagation();
			});

			var highlighted;

			if (this.options.value)
				this._select($("li[data-" + this.options.selector + "=" + this.options.value + "]", list));
			else
				this._select($("li:first-child", list));

			$("body").click(function() {
				list.hide();
			});

			var highlight = function(i) {
				highlighted = $(i);
				highlighted.addClass('selected').siblings('.selected').removeClass('selected');
			};

			var scroll = function(event) {
				list.scrollTo('.selected');
			};

			var hover = function(event) {
				highlight(this);
			};

			var rebind = function(event) {
				bind();
			};

			var bind = function() {
				list.on('mouseover', 'li', hover);
				widget.off('mousemove', rebind);
			};

			var unbind = function() {
				list.off('mouseover', 'li', hover);
				widget.on('mousemove', rebind);
			};

			list.on('click', 'li', function(event) {
				self._select(this);
				event.stopPropagation();
			});

			widget.keydown(function(event) {
				unbind();
				switch(event.keyCode) {
					case 38:
						highlight((highlighted && highlighted.prev().length > 0) ? highlighted.prev() : list.children().last());
						scroll();
						break;

					case 40:
						highlight((highlighted && highlighted.next().length > 0) ? highlighted.next() : list.children().first());
						scroll();
						break;

					case 13:
						if (highlighted) {
							select(highlighted);
						}
						break;

				}

			});

			bind();
			return widget;
		},
		destroy : function() {
			this.options.container.remove();
			$.Widget.prototype.destroy.call(this);
		}
	});

	$.fn.scrollTo = function(target, options, callback) {

		if ( typeof options === 'function' && arguments.length === 2) {

			callback = options;
			options = target;
		}

		var settings = $.extend({
			scrollTarget : target,
			offsetTop : 185,
			duration : 0,
			easing : 'linear'
		}, options);

		return this.each(function(i) {

			var scrollPane = $(this);
			var scrollTarget = ( typeof settings.scrollTarget === 'number') ? settings.scrollTarget : $(settings.scrollTarget);
			var scrollY = ( typeof scrollTarget === 'number') ? scrollTarget : scrollTarget.offset().top + scrollPane.scrollTop() - parseInt(settings.offsetTop, 10);

			scrollPane.animate({
				scrollTop : scrollY
			}, parseInt(settings.duration, 10), settings.easing, function() {

				if ( typeof callback === 'function') {

					callback.call(this);
				}

			});

		});

	};

})(jQuery);
